#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<stdio.h>
#include<vector>

using namespace std;

#define BLOCK_SIGNAL 2
#define MAX_SIGNUM 31

void Count(int cnt)
{
  while(cnt)
  {
    printf("cnt: %2d\r",cnt);
    fflush(stdout);
    cnt--;
    sleep(1);
  }
  cout<<"\n";
}

void handler(int signo)
{
  cout<<"get a signo: "<<signo<<endl;
  Count(10);//在handler方法里待十秒
}

int main()
{
 struct sigaction act,oact;
 act.sa_handler=handler;
 act.sa_flags=0;
 sigemptyset(&act.sa_mask);
 sigaddset(&act.sa_mask,3);//屏蔽2号信号的同时也屏蔽3号信号
sigaction(SIGINT,&act,&oact);

while(true) sleep(1);


  return 0;
}


// static vector<int> sigarr{2,3};//将2，3号信号添加到进程的信号屏蔽字中

// static void show_pending(sigset_t &pending)
// {
//     for(int signo=MAX_SIGNUM;signo>=1;signo--)
//     {
//         if(sigismember(&pending,signo))
//         {
//             cout<<"1";
//         }else
//         cout<<"0";
//     }
//     cout<<"\n";
// }
// void myhandler(int signo)
// {
//   cout<<signo<<"信号已经被抵达\n"<<endl;
// }
// int main()
// {
//   signal(2,myhandler);
//     //先初始化
//     sigset_t block,oblock,pending;
//     sigemptyset(&block);
//     sigemptyset(&oblock);
//     sigemptyset(&pending);
//     sigaddset(&block,BLOCK_SIGNAL);//把二号信号添加到block位图中
//   //for(const auto&sig:sigarr) sigaddset(&block,sig);
//   //把vector内指定的信号添加进block位图中
  
//     //将定义的位图设置进进程内核中
//     sigprocmask(SIG_SETMASK,&block,&oblock);
    
//     //打印pending位图
//     int cnt=10;
//   while(true)
//   {
//     sigemptyset(&pending);
//     sigpending(&pending);//获取进程的pending位图并置进pending位图中
//     show_pending(pending);//打印pending位图
//     sleep(1);//间隔打印
//     if(cnt--==0)
//     {
//       cout<<"恢复对信号的屏蔽，此时不屏蔽任何信号\n"<<endl;
//       sigprocmask(SIG_SETMASK,&oblock,&block);
      
//     }
//   }

//     return 0;
// }


//volatile int quit=0;//volatile修饰后的数据标识该数据的内存可视性，去掉编译器的优化：将数据放进cpu的寄存器中，之后不更新该数据，而是一直用该数据做运算

// void Count(int cnt)
// {
//     while(cnt)
//     {`
//         //cout<<"cnt:"<<cnt;
//         printf("cnt: %d\r",cnt);
//         fflush(stdout);
//         cnt--;
//         sleep(1);
//     }
//     cout<<"\n";
// }
// void sigcb(int signo)
// {
//  cout<<"触发这次事件的信号值是： "<<signo<<endl;
// Count(10);//每个信号阻塞10秒
// }
// int main()
// {
//    // signal(SIGINT,sigcb);
// struct sigaction act,oact;
// act.sa_handler=sigcb;
// act.sa_flags=0;
// sigemptyset(&act.sa_mask);
// sigaddset(&act.sa_mask,40);//阻塞2号信号的同时阻塞40号信号
//  sigaction(SIGINT,&act,&oact);
//     cout<<"正在等待信号中......进程的pid为： "<<getpid()<<endl;
// while(1)
// {
// sleep(1);
// }
//     return 0;
// }



// void handler(int signo)
// {
//         cout<<"quit: "<<"0->"<<quit<<endl;
//     quit=1;
//     cout<<"quit: "<<"0->"<<quit<<endl;
// }

// int main()
// {
//     signal(2,handler);
//         while(!quit);
//     return 0;
// }

// void Count(int cnt)
// {
//     while(cnt)
//     {
//         //cout<<"cnt:"<<cnt;
//         printf("cnt: %d\r",cnt);
//         fflush(stdout);
//         cnt--;
//         sleep(1);
//     }
//     cout<<"\n";
// }

// void handler(int signo)
// {
//     cout<<"get a signo: "<<signo<<"正在处理中"<<endl;
//   Count(10);
// }

// int main()
// {
//     struct sigaction act,oact;
//     act.sa_handler=handler;
//     act.sa_flags=0;
//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask,3);//当处理指定信号时，会将指定信号加入该信号屏蔽字，但不想让别的信号干扰，所以此步为当处理指定信号时，将该函数指定的信号也一并屏蔽掉
//     //当处理2号信号时，虽然屏蔽了3号信号，但是也会将该3号信号置进pending位图中，当处理完2号信号且2号信号的pending位图也为0时，就会去掉3号信号的屏蔽字，然后处理3号信号，所以进程退出
// sigaction(SIGINT,&act,&oact);
// while(true) sleep(1);
//     return 0;
// }

// static void show_pending(sigset_t &pending)
// {
//     for(int signo=MAX_SIGNUM;signo>=1;signo--)
//     {
//         if(sigismember(&pending,signo))
//         {
//             cout<<"1";
//         }else
//         cout<<"0";
//     }
//     cout<<"\n";
// }

// static vector<int> sigarr={2};//需要设置的信号

// static void handler(int signo)
// {
//     cout<<"该信号已被抵达,signo: "<<signo<<endl;
// }

// int main()
// {
// for(const auto& sig:sigarr) signal(sig,handler);//把自定义方法设置进指定的信号

// //1.把指定信号屏蔽掉
// sigset_t block,oblock,pending;
// //初始化
// sigemptyset(&block);
// sigemptyset(&oblock);
// sigemptyset(&pending);

// //添加要屏蔽的信号
// for(const auto& sig:sigarr) sigaddset(&block,sig);//添加进block位图里，将该信号置1
// //更改进程的信号屏蔽字
// sigprocmask(SIG_BLOCK,&block,&oblock);//oblock保存原先进程的位图,block通过SIG_BLOCK添加进进程的屏蔽字位图
// //遍历打印进程的pending位图
// int cnt=5;
// while(true)
// {
//     //初始化pending位图
//     sigemptyset(&pending);
//     //获取pending位图
//     sigpending(&pending);//将进程的pending位图通过输出型参数pending传出
//     //打印pending位图
//     show_pending(pending);
//     sleep(1);
//     while(cnt--==0)
//     {
//     cout<<"恢复已屏蔽的信号,现不屏蔽任何信号了"<<endl;
//     sigprocmask(SIG_SETMASK,&oblock,&block);
//     }
// }

//     return 0;
// }